import { _decorator, Component, error, instantiate, Label, Node, ProgressBar, tween, Tween, Vec3 } from 'cc';
import DataManager from '../../Global/DataManager';
import { EntityTypeEnum, IActor, InputTypeEnum, IVec2, toFixed } from '../../Common';
import { EntityManager } from '../../Base/EntityManager';
import { ActorStateMachine } from './ActorStateMachine';
import { EntityStateEnum, EventEnum } from '../../Enum';
import { WeaponManager } from '../Weapon/WeaponManager';
import { rad2Angle } from '../../Utils';
import EventManager from '../../Global/EventManager';
const { ccclass, property } = _decorator;

@ccclass('ActorManager')
export class ActorManager extends EntityManager implements IActor {
    //静态数据
    id: number;
    nickname: string;
    type: EntityTypeEnum;
    weaponType: EntityTypeEnum;
    bulletType: EntityTypeEnum;

    //动态数据
    hp: number;
    position: IVec2;
    direction: IVec2;

    private hpBar:ProgressBar
    private label: Label;
    private weapon:WeaponManager
    //目标位置
    private tw :Tween<unknown>
    private targetPos :Vec3
    private isDead = false;

    init(data:IActor){
        const { id, nickname, type, weaponType, bulletType } = data;
        
        this.id=id
        this.nickname = nickname;
        this.type = type;
        this.weaponType = weaponType;
        this.bulletType = bulletType;

        this.hpBar=this.node.getComponentInChildren(ProgressBar)
        this.label = this.node.getComponentInChildren(Label);
        this.label.string = nickname;

        this.fsm=this.addComponent(ActorStateMachine)
        this.fsm.init(type)
        //设置默认状态，并且执行其动画
        this.state=EntityStateEnum.Idle
        
        //拿武器prefab
        const weaponPrefab  = DataManager.Instance.prefabMap.get(this.weaponType)
        console.log(this.weaponType)
        const weapon  = instantiate(weaponPrefab)
        weapon.setParent(this.node)
        this.weapon=weapon.addComponent(WeaponManager)
        this.weapon.init(data)

        //初始化时不让节点显示，等renderPos的时候再显示，就不会有瞬移问题了
        this.node.active =false
        this.targetPos = undefined

    }
    //统一在btm管理，根据datamanager保存的输入值来更新玩家位置信息
    async tick(dt: number) {
        // console.log("玩家血量",this.hp)
        if(this.id!==DataManager.Instance.myPlayerId||this.isDead){
            return
        }
        if(this.hp<=0){
            console.log("玩家死亡",this.id)
            EventManager.Instance.emit(EventEnum.GameEnd)
            this.isDead=true
            return
        }
        //只有输入值的时候才会更新玩家位置，所以先判断输入值是否为空
        if(DataManager.Instance.jm.input.length()){
            const {x,y}=DataManager.Instance.jm.input
            //使用clientSync事件（battlemanager监听事件）来向服务端发送input输入值
            EventManager.Instance.emit(EventEnum.ClientSync,{
                id:DataManager.Instance.myPlayerId, //改变的玩家id
                type:InputTypeEnum.ActorMove,
                direction:{
                    x:toFixed(x),
                    y:toFixed(y),
                },
                dt:toFixed(dt), //如果游戏的每一帧的移动不是一样的话，人物的移动就不会这么顺滑
            })  
        }
    }
    /**
     * battleManager会调用这个方法，把数据渲染到场景中
     */
    render(data:IActor){     
        this.renderPos(data)
        this.renderDire(data)
        this.renderHP(data)
    }

    renderPos(data:IActor){
        const {position}=data
        const newPos = new Vec3 (position.x,position.y)
        //如果targetPos不存在（第一次渲染）
        if(!this.targetPos){
            this.node.active = true
            this.node.setPosition(newPos)
            this.targetPos = new Vec3(newPos)
            //如果目标位置不等于后端传入的值（人物移动）
        }else if(!this.targetPos.equals(newPos)){
            //如果之前有缓动，则停止之前的缓动
            this.tw?.stop()
            this.node.setPosition(this.targetPos)
            this.targetPos.set(newPos)
            //将状态改为run状态
            this.state=EntityStateEnum.Run
            this.tw = tween(this.node)
                .to(0.1,{
                    position :this.targetPos,
                })
                .call(()=>{
                    //缓动完回调，将状态改为idle状态
                    this.state=EntityStateEnum.Idle
                })
                .start()
        }
        // this.node.setPosition(position.x,position.y)
    }
    renderDire(data:IActor){
        const {x,y}=data.direction
        //左右翻转
        if(x!==0){
            this.node.setScale(x>0?1:-1,1)
            this.label.node.setScale(x > 0 ? 1 : -1, 1);
            this.hpBar.node.setScale(x > 0 ? 1 : -1, 1);
            //左右翻转血条
            this.hpBar.node.setScale(x>0?1:-1,1)
        }

        //通过虚拟摇杆给的direction来设置枪的旋转角度
        const side = Math.sqrt(x**2+y**2)
        const rad = Math.asin(y/side)
        const angle = rad2Angle(rad)
        //设定枪的旋转角度,旋转的是z轴
        this.weapon.node.setRotationFromEuler(0,0,angle)
    }
    renderHP(data:IActor){
        this.hp=data.hp
        //设置血量
        this.hpBar.progress=data.hp/this.hpBar.totalLength
    }
}

